<!DOCTYPE html>
<html lang="zh-cn">
  <head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="author" content="Zhou Wei <zromyk@163.com>">
  <title>HTTP</title>
  <link rel="shortcut icon" href="/favicon.ico">
  <link rel="stylesheet" href="/style/html/pure.css">
  <link rel="stylesheet" href="/style/html/main.css">
  <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">
  <!-- <link rel="stylesheet" href="https://apps.bdimg.com/libs/highlight.js/9.1.0/styles/default.min.css"> -->
<link rel="stylesheet" href="/style/article/highlight/default.min.css">
<link rel="stylesheet" href="/style/article/pell-1.0.6/dist/pell.css">

</head>
<body>
  <div id="menu-background"></div>
  <div id="menu">
    <div class="pure-menu pure-menu-horizontal">
  <ul class="pure-menu-list block-middle">
    <li class="pure-menu-item">
  <a class="pure-menu-heading" href="/index.html">ZROMYK</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="/index.html">主页</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="/public/archive/index.html">归档</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="/public/download/index.html">下载</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="/public/feedback/index.html">反馈</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="/public/about/index.html">关于我</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="https://github.com/zromyk"><i class="fa fa-github" style="font-size:32px"></i></a>
</li>

  </ul>
</div>

  </div>
  <div id="layout">
    <div class="content">
      <div id="nav">
    <div id="navigation" class="navigation">
  <ul class="pure-menu-list">
    <li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#http">第二章 简单的 HTTP 协议</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#21-http">2.1 HTTP协议用于客户端和服务器之间的通信</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#211">2.1.1 客户端请求报文的构成</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#212">2.1.2 服务器响应报文的构成</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#23-http">2.3 HTTP 是不保存状态的协议</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#24-uri">2.4 请求 URI 定位资源</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#25-http">2.5 告知服务器意图的 HTTP 方法</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#2151-get-post">2.1.5.1 比较 GET 与 POST</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#27">2.7 持久连接节省通信量</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#271">2.7.1 非持久连接</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#272">2.7.2 持久连接</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#273">2.7.3 线管化</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#28-cookie">2.8 使用 Cookie 的状态管理</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#http-http">第三章 HTTP 报文内的 HTTP 信息</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#33">3.3 编码提升传输速率</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#331">3.3.1 报文主体和实体主体的差异</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#332">3.3.2 压缩传输的内容编码</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#333">3.3.3 分割发送的分块传输编码</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#http_1">第四章 返回结果的 HTTP 状态码</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#http-web">第五章 与 HTTP 协作的 Web 服务器</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#51">5.1 用单台虚拟主机实现多个域名</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#52">5.2 通信数据转发程序：代理、网关、隧道</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#53">5.3 保存资源的缓存</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#531">5.3.1 缓存的有效期限</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#532">5.3.2 客户端的缓存</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#web-https">第七章 确保 Web 安全的 HTTPS</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#71-http">7.1 HTTP 的缺点</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#711">7.1.1 加密</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav5" onclick="animateByNav()" href="#_1">通信的加密</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav5" onclick="animateByNav()" href="#_2">内容的加密</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#72-httphttps">7.2 HTTP+加密+认证+完整性保护=HTTPS</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#723-https">7.2.3 HTTPS 采用混合加密机制</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#725-https">7.2.5 HTTPS 的安全通信步骤</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#_3">第八章 确认访问用户身份的认证</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#81">8.1 何为认证</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#web">第十一章 Web 的攻击技术</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#111-web">11.1 针对 Web 的攻击技术</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#1111-http">11.1.1 HTTP 不具备必要的安全功能</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#1113-web">11.1.3 针对 Web 应用的攻击模式</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#11131">11.1.3.1 以服务器为目标的主动攻击</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#11132">11.1.3.2 以服务器为目标的被动攻击</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#112">11.2 因输出转义不完全引发的安全漏洞</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#1121">11.2.1 跨站脚本攻击</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#1122-sql">11.2.2 SQL 注入攻击</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#1123-os">11.2.3 OS 命令注入攻击</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#1124-http">11.2.4 HTTP 首部注入攻击</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#1125">11.2.5 邮件首部注入攻击</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#1126">11.2.6 目标遍历攻击</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#1127">11.2.7 远程文件包含漏洞</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#nginx">Nginx 反向代理</a>
</li>

  </ul>
</div>

</div>
<div id="content-articles">
  <h1 id="HTTP" class="content-subhead">HTTP</h1>
  <p>
    <span>2021-04-21</span>
    <span><span class="post-category post-category-web">Web</span></span>
    <button id="button-markdownEditor" class="pure-button" onclick="markdownEditor()">启用编辑</button>
    <button id="button-save" class="pure-button" onclick="save()">保存</button>
  </p>
  <div id="content-articles-markdownEditor" style="display: none;">
    <h1>编辑 power by pell</h1>
    <div id="editor" class="pell"></div>
    <div style="margin-top:20px;">
        <h3>Text output:</h3>
        <div id="text-output"></div>
    </div>
    <div style="margin-top:20px;">
        <h3>HTML output:</h3>
        <pre id="html-output"></pre>
    </div>
  </div>
  <div id="content-articles-markdown">
    <blockquote class="content-quote">
<p>未完待续，来自《图解 HTTP》</p>
</blockquote>
<h2 id="http">第二章 简单的 HTTP 协议</h2>
<h3 id="21-http">2.1 HTTP协议用于客户端和服务器之间的通信</h3>
<h4 id="211">2.1.1 客户端请求报文的构成</h4>
<blockquote class="content-quote">
<p>URI：统一资源标志符</p>
<p>URL：统一资源定位符</p>
<p>URI 包含 URL</p>
</blockquote>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code>方法     URI      协议版本
---- ----------- --------
POST /index.html HTTP/1.1

Host: hacker.jp
Connection: keep-alive
Content-Type: ...
Content-Length: ...
</code></span></code></pre>
<p>GET 表示请求访问服务器的类型，称为方法。</p>
<p>随后的字符串 /index.html 指明了请求访问的资源对象，叫做请求 URI（request-URI）</p>
<p>最后的 HTTP/1.1，即 HTTP 的版本号，用来提示客户端使用的 HTTP 协议。</p>
<h4 id="212">2.1.2 服务器响应报文的构成</h4>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code>协议版本 状态码 状态码的原因短语
------ ----- -------------       响应首部字段
HTTP/1.1 200 OK                  ----------
Date: Tue, 10, Jul 2012 06:50:15 GMT
Content-Length: ...
Content-Type: ...
[空行]
资源主体
------
&lt;html&gt;
...
</code></span></code></pre>
<p>HTTP/1.1 表示服务器对应的 HTTP 版本。</p>
<p>200 OK 表示请求测处理结果的状态码（status code）和原因短语（reason-phrase）。</p>
<p>创建响应的时间日期。</p>
<p>资源实体的主体（entity body）</p>
<h3 id="23-http">2.3 HTTP 是不保存状态的协议</h3>
<p>HTTP 是不保存状态的协议，即无状态协议。HTTP 协议自身不对请求和响应之间的通信状态进行保存。在 HTTP 这个级别，协议对于发送过的请求或响应都不做持久化处理。</p>
<h3 id="24-uri">2.4 请求 URI 定位资源</h3>
<p>HTTP 协议使用 URI 定位互联网上的资源。</p>
<p>因为 URI 的特定功能，在互联网上任意的资源都能访问到。</p>
<h3 id="25-http">2.5 告知服务器意图的 HTTP 方法</h3>
<div class="pure-table-scrollable"><table class="pure-table pure-table-horizontal">
<thead>
<tr>
<th>方法</th>
<th>目的</th>
<th>支持 HTTP  协议版本</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>GET</td>
<td>获取资源</td>
<td>1.0、1.1</td>
<td>GET 用于从指定资源请求数据。<br />GET 是最常见的 HTTP 方法之一。<br />请注意，查询字符串（名称/值对）是在 GET 请求的 URL 中发送的。<br /><br />有关 GET 请求的其他一些注释：<br/>GET 请求可被缓存<br/>GET 请求保留在浏览器历史记录中<br/>GET 请求可被收藏为书签<br/>GET 请求不应在处理敏感数据时使用<br/>GET 请求有长度限制<br/>GET 请求只应当用于取回数据（不修改）</td>
</tr>
<tr>
<td>POST</td>
<td>传输实体主体</td>
<td>1.0、1.1</td>
<td>用于 <strong>将数据发送到服务器</strong> 来创建/更新资源。<br />POST 是最常见的 HTTP 方法之一。<br /><br />有关 POST 请求的其他一些注释：<br />POST 请求不会被缓存<br />POST 请求不会保留在浏览器历史记录中<br />POST 不能被收藏为书签<br />POST 请求对数据长度没有要求</td>
</tr>
<tr>
<td>PUT</td>
<td>传输文件</td>
<td>1.0、1.1</td>
<td>PUT 用于 <strong>将数据发送到服务器</strong> 来创建/更新资源。<br />POST 和 PUT 之间的区别在于 PUT 请求是幂等的（idempotent）。<br /><strong>也就是说，多次调用相同的 PUT 请求将始终产生相同的结果。</strong><br /><strong>相反，重复调用 POST 请求具有多次创建相同资源的副作用。</strong></td>
</tr>
<tr>
<td>HEAD</td>
<td>获得报文首部</td>
<td>1.0、1.1</td>
<td>HEAD 与 GET 几乎相同，但 <strong>没有响应主体</strong>。<br />HEAD 可以用来确认 URI 的有效性及资源更新的日期时间等。<br /><br />换句话说，如果 GET /users 返回用户列表，那么 HEAD /users 将发出相同的请求，但不会返回用户列表。<br/>HEAD 请求对于在实际发出 GET 请求之前（例如在下载大文件或响应正文之前）检查 GET 请求将返回的内容很有用。</td>
</tr>
<tr>
<td>DELETE</td>
<td>删除文件</td>
<td>1.0、1.1</td>
<td>DELETE 方法按请求 URI 删除指定的资源，是与 PUT 相反的方法。</td>
</tr>
<tr>
<td>OPTIONS</td>
<td>询问支持的方法</td>
<td>1.1</td>
<td>OPTIONS 方法用来查询针对请求 URI 指定的资源支持方法。</td>
</tr>
<tr>
<td>TRACE</td>
<td>追踪路径</td>
<td>1.1</td>
<td>TRACE 方法是让 Web 服务器将之前请求的通信环回给客户端的方法。<br />客户端通过 TRACE 方法可以查询发送出去的请求是这样被加工修改 / 篡改的。<br />TRACE 本来就不怎么常用，加上它容易引发 XST 跨站追踪攻击，通常就更不会用到了。</td>
</tr>
<tr>
<td>CONNECT</td>
<td>要求用隧道协议连接代理</td>
<td>1.1</td>
<td>CONNECT 方法要求在与代理服务器通信时简历隧道，实现隧道协议进行 TCP 通信。主要使用 SSL（Secure Sockets Layer，安全套接层）和 TLS（Transport Layer Security，传输层安全）协议把通信内容加密后经网络隧道传输。<br /><span style="overflow-x: auto; max-width:100%; display:inline;"><code>CONNECT 代理服务器名:端口号 HTTP 版本</code></span></td>
</tr>
<tr>
<td>LINK</td>
<td>建立和资源之间的联系</td>
<td>1.0</td>
<td></td>
</tr>
<tr>
<td>UNLINK</td>
<td>断开连接关系</td>
<td>1.0</td>
<td></td>
</tr>
</tbody>
</table></div>
<h4 id="2151-get-post">2.1.5.1 比较 GET 与 POST</h4>
<p>下面的表格比较了两种 HTTP 方法：GET 和 POST。</p>
<div class="pure-table-scrollable"><table class="pure-table pure-table-horizontal">
<thead>
<tr>
<th align="left"></th>
<th align="left">GET</th>
<th align="left">POST</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">后退按钮/刷新</td>
<td align="left">无害</td>
<td align="left">数据会被重新提交<br />（浏览器应该告知用户数据会被重新提交）。</td>
</tr>
<tr>
<td align="left">书签</td>
<td align="left">可收藏为书签</td>
<td align="left">不可收藏为书签</td>
</tr>
<tr>
<td align="left">缓存</td>
<td align="left">能被缓存</td>
<td align="left">不能缓存</td>
</tr>
<tr>
<td align="left">编码类型</td>
<td align="left">application/x-www-form-urlencoded</td>
<td align="left">application/x-www-form-urlencoded 或 multipart/form-data。<br />为二进制数据使用多重编码。</td>
</tr>
<tr>
<td align="left">历史</td>
<td align="left">参数保留在浏览器历史中。</td>
<td align="left">参数不会保存在浏览器历史中。</td>
</tr>
<tr>
<td align="left">对数据长度的限制</td>
<td align="left">是的。<br />当发送数据时，GET 方法向 URL 添加数据；<br />URL 的长度是受限制的（URL 的最大长度是 2048 个字符）。</td>
<td align="left">无限制。</td>
</tr>
<tr>
<td align="left">对数据类型的限制</td>
<td align="left">只允许 ASCII 字符。</td>
<td align="left">没有限制。也允许二进制数据。</td>
</tr>
<tr>
<td align="left">安全性</td>
<td align="left">与 POST 相比，GET 的安全性较差，因为所发送的数据是 URL 的一部分。<br />在发送密码或其他敏感信息时绝不要使用 GET ！</td>
<td align="left">POST 比 GET 更安全，因为参数不会被保存在浏览器历史或 web 服务器日志中。</td>
</tr>
<tr>
<td align="left">可见性</td>
<td align="left">数据在 URL 中对所有人都是可见的。</td>
<td align="left">数据不会显示在 URL 中。</td>
</tr>
</tbody>
</table></div>
<h3 id="27">2.7 持久连接节省通信量</h3>
<h4 id="271">2.7.1 非持久连接</h4>
<p>HTTP 协议的初始版本中，每进行一次 HTTP 通信就要断开 TCP 连接。</p>
<p><img class="pure-img" src="https://zromyk.gitee.io/myblog-figurebed/post/HTTP.assets/截屏2021-04-20 21.40.49.png" alt="截屏2021-04-20 21.40.49" style="zoom: 50%;" /></p>
<h4 id="272">2.7.2 持久连接</h4>
<p>HTTP/1.1 和一部分 HTTP/1.0 想出了持久连接的方法。只要任意一端没有明确剔除断开连接，则保持 TCP 连接状态。</p>
<p><img class="pure-img" src="https://zromyk.gitee.io/myblog-figurebed/post/HTTP.assets/截屏2021-04-20 21.42.55.png" alt="截屏2021-04-20 21.42.55" style="zoom:50%;" /></p>
<ul>
<li>一方面，减少了 TCP 连接的重复建立和断开所造成的额外开销，减轻了服务器的负载。</li>
<li>另外，减少开销的那部分，使 HTTP 请求和响应能够更早地结束，这样 Web 页面的显示速度也就相应提高了。</li>
</ul>
<p><strong>在 HTTP/1.1 中，所有的连接默认都是持久连接</strong>，但在 HTTP/1.0 内并未标准化。</p>
<h4 id="273">2.7.3 线管化</h4>
<p>持久连接使得多数请求以线管化方式发送成为可能。</p>
<p><img class="pure-img" src="https://zromyk.gitee.io/myblog-figurebed/post/HTTP.assets/截屏2021-04-20 21.46.50.png" alt="截屏2021-04-20 21.46.50" style="zoom:50%;" /></p>
<h3 id="28-cookie">2.8 使用 Cookie 的状态管理</h3>
<p>HTTP 是无状态协议，他不对之前发生过的请求和响应的状态进行管理。</p>
<p><strong>Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。</strong></p>
<p>Cookie 会根据从服务器发送的响应报文内一个叫做 Set-Cookie 的首部段信息，<strong>通知客户端保存 Cookie</strong>。下次客户端再往该服务器发送请求时，客户端会自动在请求报文中加入 Cookie 值后发送出去。</p>
<p>服务端发现客户端发送过来的 Cookie 后，回去检查究竟是从哪个客户端发来的连接请求，然后对比服务器上的记录，最后得到之前的状态信息。</p>
<h2 id="http-http">第三章 HTTP 报文内的 HTTP 信息</h2>
<h3 id="33">3.3 编码提升传输速率</h3>
<h4 id="331">3.3.1 报文主体和实体主体的差异</h4>
<p>报文：HTTP 通信中的基本单位，由 8 位组字节流组成，通过 HTTP 通信传输。</p>
<p>实体：作为请求或响应的有效载荷数据被传输，其内容由实体首部和实体主体组成。</p>
<h4 id="332">3.3.2 压缩传输的内容编码</h4>
<p>HTTP 协议内有一种被称为内容编码的功能，也能进行类似 ZIP 压缩的操作。</p>
<p>常用的编码由下面几种：</p>
<ul>
<li>gzip（GNU zip）</li>
<li>compress（UNIX 系统的标准压缩）</li>
<li>deflate（zlib）</li>
<li>identity（不进行编码）</li>
</ul>
<h4 id="333">3.3.3 分割发送的分块传输编码</h4>
<p>在 HTTP 通信过程中，请求的编码实体资源尚未全部传输完成之前，浏览器无法显示请求页面。在传输大容量数据时，通过把数据分割成多块，能够让浏览器逐步显示页面。</p>
<p>HTTP/1.1 中存在一种称为传输编码的机制，他可以在通信时按某种编码方式传输，但只定义作用于分块传输编码中。</p>
<h2 id="http_1">第四章 返回结果的 HTTP 状态码</h2>
<div class="pure-table-scrollable"><table class="pure-table pure-table-horizontal">
<thead>
<tr>
<th></th>
<th>类别</th>
<th>中文含义</th>
<th>原因短语</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>1XX</strong></td>
<td><strong>Informational</strong></td>
<td><strong>信息状态码</strong></td>
<td><strong>接收的请求正在处理</strong></td>
</tr>
<tr>
<td><strong>2XX</strong></td>
<td><strong>Success</strong></td>
<td><strong>成功状态码</strong></td>
<td><strong>请求正常处理完毕</strong></td>
</tr>
<tr>
<td>200</td>
<td>OK</td>
<td></td>
<td>请求已正常处理</td>
</tr>
<tr>
<td>204</td>
<td>No Content</td>
<td></td>
<td>请求处理成功，但没有资源可返回</td>
</tr>
<tr>
<td>206</td>
<td>Parital Content</td>
<td></td>
<td>请求成功，服务器返回客户端请求资源（客户端只请求部分资源）</td>
</tr>
<tr>
<td><strong>3XX</strong></td>
<td><strong>Redirection</strong></td>
<td><strong>重定向状态码</strong></td>
<td><strong>需要进行附加操作以完成请求</strong></td>
</tr>
<tr>
<td>301</td>
<td>Moved Permanently</td>
<td></td>
<td>永久性重定向，该状态码表示请求的资源已被分配了新的 URI，以后应使用资源现在所指向的 URI。</td>
</tr>
<tr>
<td>302</td>
<td>Found</td>
<td></td>
<td>临时性重定向，该状态码表示请求的资源已被分配了新的 URI，希望用户（本次）能使用新的 URI。</td>
</tr>
<tr>
<td>303</td>
<td>See Other</td>
<td></td>
<td>该状态吗表示由于请求对应的资源存在另一个 URI，应 <strong>使用 GET 方法</strong> 定向获取请求的资源。<br />例如：当使用 POST 方法访问 CGI 程序，其执行的处理结果时希望客户端能以 GET 方法重定向到另一个 URI 上去。</td>
</tr>
<tr>
<td>304</td>
<td>Not Modified</td>
<td></td>
<td>该状态码表示客户端发送附带条件的请求时，服务器允许请求访问资源，但未满足条件的情况。（304 虽然被划分在 3XX 中，但和重定向没有关系。）</td>
</tr>
<tr>
<td>307</td>
<td>Temporary Redirect</td>
<td></td>
<td>临时重定向。</td>
</tr>
<tr>
<td><strong>4XX</strong></td>
<td><strong>Client Error</strong></td>
<td><strong>客户端错误状态码</strong></td>
<td><strong>服务器无法处理请求</strong></td>
</tr>
<tr>
<td>400</td>
<td>Bad Request</td>
<td></td>
<td>该状态码表示请求报文中存在语法错误。</td>
</tr>
<tr>
<td>401</td>
<td>Unauthorized</td>
<td></td>
<td>该状态码表示发送的请求需要有通过 HTTP 认证的认证信息。<br />返回的响应中包含质询用户信息，当浏览器初次接收到 401 响应时，会弹出认证用的对话窗口。</td>
</tr>
<tr>
<td>403</td>
<td>Forbidden</td>
<td></td>
<td>该状态码表明对请求资源的访问被服务器拒绝了。<br />服务器可以在实体的主体部分进行原因描述。<br />未获得文件系统的访问权限，或从未授权的 IP 访问都可能发生 403。</td>
</tr>
<tr>
<td>404</td>
<td>Not Found</td>
<td></td>
<td>服务器上没有请求的资源。</td>
</tr>
<tr>
<td><strong>5XX</strong></td>
<td><strong>Server Error</strong></td>
<td><strong>服务器错误状态码</strong></td>
<td><strong>服务器处理请求出错</strong></td>
</tr>
<tr>
<td>500</td>
<td>Internal Server Error</td>
<td></td>
<td>服务器在执行请求时发生了错误。可能是 Web 应用存在 bug 或某些临时的故障。</td>
</tr>
<tr>
<td>503</td>
<td>Service Unavailable</td>
<td></td>
<td>服务器暂时处于超负载或正在进行停机维护，现在无法处理请求。<br />服务器可以在 Retry-After 首部字段返回解除以上状态的时间给客户端。</td>
</tr>
</tbody>
</table></div>
<h2 id="http-web">第五章 与 HTTP 协作的 Web 服务器</h2>
<h3 id="51">5.1 用单台虚拟主机实现多个域名</h3>
<p>HTTP/1.1 规范允许一台 HTTP 服务器搭建多个 Web 站点。</p>
<p>通过虚拟主机（Virtual Host，又称虚拟服务器），即使物理层面只有一台服务器，但只要使用虚拟主机功能，则可以假想成多台服务器。</p>
<h3 id="52">5.2 通信数据转发程序：代理、网关、隧道</h3>
<ul>
<li>代理：代理是一种有转发功能的应用程序，接收客户端的请求，并转发给服务器。</li>
<li>缓存代理：代理转发响应时，缓存代理会预先将资源的副本缓存保存在代理服务器上。当代理再次接受到对相同资源的请求时，就可以不从原服务器那里获取资源，而是将之前缓存的资源作为响应返回。</li>
<li>透明代理：转发请求或响应时，不对报文做任何加工的代理类型被称为透明代理。</li>
<li>非透明代理：对报文内容进行加工的代理。</li>
<li>网关：转发其他服务器通信数据的服务器，接收从客户端发送来的请求时，它就像自己拥有资源的源服务器一样对请求进行处理。</li>
<li>网关能够提高通信的安全性，可以再客户端与网关之间的通信线路上加密确保连接的安全。</li>
<li>隧道：相隔甚远的客户端和服务器两者之间进行中转，并保持双方通信连接的应用程序。</li>
<li>隧道本身不会去解析 HTTP 请求。请求保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。</li>
<li>隧道本身是透明的，客户端不用在意隧道的存在。</li>
</ul>
<h3 id="53">5.3 保存资源的缓存</h3>
<p>缓存是指代理服务器或客户端 <strong>本地磁盘</strong> 内保存的资源副本。</p>
<p>利用缓存可以减少对源服务器的访问，节省通信流量和通信时间。</p>
<p>缓存服务器是代理服务器的一种，它可以避免多次从源服务器转发资源。</p>
<h4 id="531">5.3.1 缓存的有效期限</h4>
<h4 id="532">5.3.2 客户端的缓存</h4>
<p>缓存不经可以存在于缓存服务器内，还可以存在客户端浏览器中。</p>
<h2 id="web-https">第七章 确保 Web 安全的 HTTPS</h2>
<h3 id="71-http">7.1 HTTP 的缺点</h3>
<ul>
<li>通信使用明文（不加密），内容可能被窃听。</li>
<li>不验证通信方的身份，因此有可能遭遇伪装。</li>
<li>无法证明报文的完整性，所以有可能已经被篡改。</li>
</ul>
<h4 id="711">7.1.1 加密</h4>
<h5 id="_1">通信的加密</h5>
<p>通过 SSL（Secure Cocket Layer，安全套接层）或 TLS（Transport Layer Security，安全层传输协议）的组合使用，对 HTTP 内容进行加密。</p>
<p>用 SSL 建立安全通信线路之后，就可以在这条线路上进行 HTTP 通信。</p>
<p>与 SSL 组合使用的 HTTP 被称为 HTTPS（HTTP Secure，超文本传输安全协议）</p>
<h5 id="_2">内容的加密</h5>
<p>直接对 HTTP 报文主体进行加密处理后再发送请求。（报文首部不加密）</p>
<p>该种加密方式，有内容被篡改的风险。</p>
<h3 id="72-httphttps">7.2 HTTP+加密+认证+完整性保护=HTTPS</h3>
<p>HTTPS 是身披 SSL 外壳的 HTTP</p>
<div class="pure-table-scrollable"><table class="pure-table pure-table-horizontal">
<thead>
<tr>
<th>HTTP</th>
<th>HTTPS</th>
</tr>
</thead>
<tbody>
<tr>
<td>应用</td>
<td>应用</td>
</tr>
<tr>
<td></td>
<td>SSL</td>
</tr>
<tr>
<td>TCP</td>
<td>TCP</td>
</tr>
<tr>
<td>IP</td>
<td>IP</td>
</tr>
</tbody>
</table></div>
<p>可以说 SSL 是当今世界上应用最为广泛的网络安全技术。</p>
<h4 id="723-https">7.2.3 HTTPS 采用混合加密机制</h4>
<p><img class="pure-img" alt="image-20210421173453096" src="https://zromyk.gitee.io/myblog-figurebed/post/HTTP.assets/image-20210421173453096.png" /></p>
<p><img class="pure-img" alt="image-20210421173709171" src="https://zromyk.gitee.io/myblog-figurebed/post/HTTP.assets/image-20210421173709171.png" /></p>
<h3 id="725-https">7.2.5 HTTPS 的安全通信步骤</h3>
<div class="pure-table-scrollable"><table class="pure-table pure-table-horizontal">
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td><img class="pure-img" alt="image-20210421173757188" src="https://zromyk.gitee.io/myblog-figurebed/post/HTTP.assets/image-20210421173757188.png" /></td>
<td><img class="pure-img" alt="image-20210421173100030" src="https://zromyk.gitee.io/myblog-figurebed/post/HTTP.assets/image-20210421173100030.png" /></td>
</tr>
</tbody>
</table></div>
<h2 id="_3">第八章 确认访问用户身份的认证</h2>
<h3 id="81">8.1 何为认证</h3>
<p>核对“只有登陆者本人才知道的信息”：</p>
<ul>
<li>密码：只有本人才会知道的字符串信息。</li>
<li>动态令牌：仅限本人持有的设备内显示的一次性密码。</li>
<li>数字证书：仅限本人，终端，持有的信息。</li>
<li>生物认证：指纹和虹膜等本人的生理信息。</li>
<li>IC 卡等：仅限本人持有的信息。</li>
</ul>
<p>HTTP 使用的认证方式：（以下为 HTTP/1.1 使用的认证方式）</p>
<ul>
<li>BASIC 认证（基本认证）：发送明文账户和密码。（Base64 编码，非加密处理）</li>
<li>DIGEST 认证（摘要认证）：客户端通过服务器发来的质询码，计算生成响应码然后发送给服务器。</li>
<li>SSL 客户端认证：一般不会仅依靠证书完成认证，一般会基于表单认证组合形成一种双因素认证。</li>
<li>FormBase 认证（基于表单认证）</li>
</ul>
<p>HTTP 认证多半为基于表单认证。</p>
<h2 id="web">第十一章 Web 的攻击技术</h2>
<h3 id="111-web">11.1 针对 Web 的攻击技术</h3>
<p>简单的 HTTP 协议本省并不存在安全性问题，因此协议本身技术不会成为攻击的对象。</p>
<p>应用 HTTP 协议的服务器和客户端，以及运行在服务器上的 Web 应用等资源才是攻击目标。</p>
<p><img class="pure-img" src="https://zromyk.gitee.io/myblog-figurebed/post/HTTP.assets/截屏2021-04-21 19.07.57.png" alt="截屏2021-04-21 19.07.57" style="zoom:50%;" /></p>
<h4 id="1111-http">11.1.1 HTTP 不具备必要的安全功能</h4>
<ul>
<li>现如今所有的 Web 网站都会使用会话管理、加密处理等安全性方面的功能，而 HTTP 协议内并不具备这些功能。而远程登录时会用到的 SSH 协议具备协议级别的认证及会话管理等功能。</li>
<li>在 Web 应用中，从浏览器那接收到的 HTTP 请求的全部内容，都可以在客户端自由地变更、篡改。</li>
<li>在 HTTP 请求报文内加载攻击代码，就能发起对 Web 应用的攻击。<ul>
<li>URL 查询字段或表单</li>
<li>HTTP 首部</li>
<li>Cookie</li>
</ul>
</li>
<li>上述途径，把攻击代码传入服务器，若此时 Web 应用存在安全漏洞，那么内部信息就会遭到窃取，或被攻击者拿到管理权限</li>
</ul>
<h3 id="1113-web">11.1.3 针对 Web 应用的攻击模式</h3>
<h4 id="11131">11.1.3.1 以服务器为目标的主动攻击</h4>
<p>主动攻击：</p>
<p>攻击者通过直接访问 Web 应用，把攻击代码传入的攻击模式。该模式直接针对服务器上的资源进行攻击，因此攻击者需要能够访问到那些资源。</p>
<p>代表性的攻击：</p>
<ul>
<li>SQL 注入攻击</li>
<li>OS 命令注入攻击</li>
</ul>
<h4 id="11132">11.1.3.2 以服务器为目标的被动攻击</h4>
<p>被动攻击：</p>
<p>利用圈套策略执行攻击代码的攻击模式。在被动攻击中，攻击者不直接对目标 Web 应用访问发起攻击。</p>
<h3 id="112">11.2 因输出转义不完全引发的安全漏洞</h3>
<ul>
<li>
<p>客户端的验证</p>
</li>
<li>
<p>Web 应用端（服务器端）的验证</p>
<ul>
<li>输入值验证</li>
<li>输出值转义</li>
</ul>
</li>
</ul>
<h4 id="1121">11.2.1 跨站脚本攻击</h4>
<h4 id="1122-sql">11.2.2 SQL 注入攻击</h4>
<p>针对 Web 应用使用的数据库，通过运行非法 SQL 而产生的攻击。该安全隐患有可能引发极大的威胁，有时会直接导致个人信息及机密信息的泄露。</p>
<blockquote class="content-quote">
<p>SQL 是用来操作关系型数据库管理系统的数据库语言。</p>
</blockquote>
<h4 id="1123-os">11.2.3 OS 命令注入攻击</h4>
<p>通过 Web 应用，执行非法的操作系统命令达到攻击的目的。只要在能调用 Shell 函数的地方就存在被攻击的风险。</p>
<p>从 Web 应用中通过 Shell 来调用操作系统命令。倘若调用 Shell 时存在疏漏，就可以执行插入的非法 OS 命令。</p>
<h4 id="1124-http">11.2.4 HTTP 首部注入攻击</h4>
<p>攻击者通过在响应首部字段内插入换行，添加任意响应首部或主体的一种攻击。</p>
<p>HTTP 首部注入攻击有可能造成以下一些影响。</p>
<ul>
<li>设置任何 Cookie 信息。</li>
<li>重定向至任何 URL</li>
<li>显式任意主体（HTTP 响应截断攻击）</li>
</ul>
<h4 id="1125">11.2.5 邮件首部注入攻击</h4>
<h4 id="1126">11.2.6 目标遍历攻击</h4>
<p>本无意公开的目录被非法截断其路径后，达成访问目的的一种攻击。</p>
<h4 id="1127">11.2.7 远程文件包含漏洞</h4>
<blockquote class="content-quote">
<p>未完待续，来自《图解 HTTP》</p>
</blockquote>
<h2 id="nginx">Nginx 反向代理</h2>
<p>Nginx 反向代理功能的特点：</p>
<p>当客户端发来 HTTP 请求，Nginx 并不会立刻转发到上游服务器，而是先把用户的请求（包括 HTTP 包体）完整地接收到 Nginx 所在服务器的硬盘或者内存中，然后向上游服务器发起连接，把缓存的客户端请求转发到上游服务器。</p>
<p>而 Squid 等代理服务器则采用一边接受客户端请求，一边转发到上游服务器的方式。</p>
<p>Nginx 的这种工作方式的优点：</p>
<ul>
<li>降低了上游服务器的负载。</li>
<li>原因：通常客户端与代理服务器之间的网络环境比较复杂，多半是走公网，网速平均较慢，而代理服务器和上游服务器之间一般走内网，或有专门传输线连接，传输较快。这种方式可以不用一直维护代理服务器与上游服务器之间的连接，可以减少上游服务器的负载。</li>
</ul>
<p>缺点：</p>
<ul>
<li>延长了一个请求的处理时间。</li>
</ul>
  </div>
</div>
 
    </div>
  </div>
  <div id="footer-background">
    <div id="footer">
      <div class="legal pure-g">
  <div class="pure-u-1 u-sm-1-2">
    <p class="legal-license"><a href="https://beian.miit.gov.cn/#/Integrated/index">浙ICP备2020038748号</a></p>
  </div>
  <div class="pure-u-1 u-sm-1-2">
    <p class="legal-links"><a href="https://github.com/zromyk">GitHub</a></p>
    <p class="legal-copyright">Copyright © 2021 Wei Zhou. 保留所有权利。</p>
  </div>
</div>
    </div>
  </div>
  <!-- <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> -->
  <script src="/style/html/jquery.min.js"></script>
  <script src='/style/article/latex/latest.js?config=TeX-MML-AM_CHTML'></script>
<!-- <script src="https://cdn.geogebra.org/apps/deployggb.js"></script> -->
<script src="/style/article/deployggb.js"></script>
<!-- <script src="https://apps.bdimg.com/libs/highlight.js/9.1.0/highlight.min.js"></script> -->
<script type="text/javascript">
  // 脚本：navigation 随鼠标移动自动变换宽度
  var element = document.getElementById("navigation"); // 获取要操作的元素
  var elementWidth = parseInt(getComputedStyle(element).width);
  var elementLeft = 0;
  var elementRight = 0;
  element.addEventListener('mouseenter', function (event) { // 添加鼠标按下事件的监听器
    elementLeft = element.getBoundingClientRect().left - 10;
    elementRight = element.getBoundingClientRect().left + elementWidth * 3;
    window.addEventListener('mousemove', resize); // 添加全局的鼠标移动事件的监听器
  });

  function resize(event) {
    var minWidth = elementWidth;
    var maxWidth = elementWidth * 2.5;
    // console.log(elementLeft, event.clientX, elementRight, event.clientX - elementLeft + elementWidth / 2);
    if (elementLeft <= event.clientX && event.clientX <= elementRight) {
      var width = event.clientX - elementLeft + elementWidth / 2;
      width = Math.min(width, maxWidth);
      width = Math.max(width, minWidth);
      element.style.width = width + 'px'; // 设置新的宽度样式属性
    }
    else {
      element.style.width = elementWidth + 'px'; // 设置新的宽度样式属性
      stopResize();
    }
  }

  function stopResize() {
    element.style.width = elementWidth + 'px'; // 设置新的宽度样式属性
    // console.log("stopResize", elementLeft, event.clientX, elementRight, event.clientX - elementLeft + elementWidth / 2);
    window.removeEventListener('mousemove', resize); // 移除鼠标移动事件的监听器
  }
</script>
<script src="/style/article/highlight/highlight.min.js"></script>
<script type="text/javascript">
  // 脚本：code语法高亮
  hljs.initHighlightingOnLoad();
</script>
<script>
  function animateByNav() {
    $("html").animate({
        scrollTop: ($(event.target.hash).offset().top - 52)
    }, 300);
  };
</script>
<script src="/style/article/pell-1.0.6/dist/pell.js"></script>
<script>
  // 脚本：自由编辑页面
  var editor = window.pell.init({
    element: document.getElementById('editor'),
    defaultParagraphSeparator: 'p',
    onChange: function(html) {
        document.getElementById('text-output').innerHTML = html
        document.getElementById('html-output').textContent = html
    }
  });

  function markdownEditor() {
    var articles = document.getElementById('content-articles-markdown');
    if (articles.getAttribute("contenteditable") == "true") {
        articles.setAttribute("contenteditable", "false");
        document.getElementById("content-articles-markdownEditor").style.display = "none"; //隐藏
        document.getElementById("button-markdownEditor").innerHTML = "启用编辑";
    } else {
        articles.setAttribute("contenteditable", "true");
        document.getElementById("content-articles-markdownEditor").style.display = ""; //显示
        document.getElementById("button-markdownEditor").innerHTML = "关闭编辑";
    }
  };

  function save() {
      window.alert("保存成功");
  };
</script>

</body>
</html>
